#ifdef __cplusplus
extern "C" {
#endif

#include <stdbool.h>
#include <stddef.h>

#if defined(WL_OS_MG)
#elif defined(WL_OS_U8910)
#elif defined(WL_OS_QUECTEL)
#else  // default linux
// #    define WL_MALLOC_CHECK
#endif

typedef struct Block Block;

struct Block {
    void*  addr;
    Block* next;
    size_t size;
#ifdef WL_MALLOC_CHECK
    char*  func;
    size_t line;
#endif
};

/*
 * 三个内存分区
 * free为已分配未使用内存块
 * used为已使用内存块
 * fresh为未分配内存块
 */
typedef struct {
    Block* free;   // first free block
    Block* used;   // first used block
    Block* fresh;  // first available blank block
    size_t top;    // top free addr

    const void* heap_limit;         //内存区大小
    size_t      heap_split_thresh;  //内存切割最小长度
    size_t      heap_alignment;     //对齐大小
    size_t      heap_max_blocks;    //内存块数量上限
} Heap;

bool ta_init(Heap*        heap,
             const void*  limit,
             const size_t heap_blocks,
             const size_t split_thresh,
             const size_t alignment);
#ifdef WL_MALLOC_CHECK
void* ta_alloc_debug(size_t num, char* func, size_t line);
#endif
void* ta_alloc(Heap* heap, size_t num);
void* ta_calloc(Heap* heap, size_t num, size_t size);
bool  ta_free(Heap* heap, void* ptr);

size_t ta_mem_size(Heap* heap, void* ptr);
size_t ta_num_free(Heap* heap);
size_t ta_num_used(Heap* heap);
size_t ta_num_fresh(Heap* heap);
size_t ta_free_size(Heap* heap);
size_t ta_used_size(Heap* heap);
size_t ta_fresh_size(Heap* heap);
bool   ta_check(Heap* heap);

#ifdef __cplusplus
}
#endif
